package com.mm.ai.service.impl;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.command.WaitContainerResultCallback;
import com.github.dockerjava.api.model.Network;
import com.github.dockerjava.api.model.RestartPolicy;
import com.google.common.base.Joiner;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.mm.ai.service.DockerContainerService;
import com.mm.ai.utils.DockerUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

import static com.mm.ai.utils.DockerUtil.TONGXINHUI_NETWORK;

/**
 * @Author： tzy
 * @Date： 2024/11/17 20:44
 */
@Service
public class DockerContainerServiceImpl implements DockerContainerService {
    private final String[] WECHAT_LOGIN_QRCODE_URL_PREFIXES = {
            "https://api.isoyu.com/qr/?m=1&e=L&p=20&url",
            "https://api.qrserver.com/v1/create-qr-code/?size=400×400&data",
            "https://api.pwmqr.com/qrcode/create/?url" + ".*",
            "https://my.tv.sohu.com/user/a/wvideo/getQRCode.do?text"
    };

    @Autowired
    private DockerClient dockerClient;
    @Autowired
    private DockerUtil dockerUtil;

    @Override
    public void createContainer(String imageName, String containerName) throws Exception {
        // 创建 tongxinhui-ai-bot 容器
        CreateContainerResponse container = dockerClient.createContainerCmd("zhayujie/chatgpt-on-wechat")
                .withName("tongxinhui2")
                .withRestartPolicy(RestartPolicy.alwaysRestart())
                .withNetworkMode(TONGXINHUI_NETWORK)
                .withEnv(
                        "OPEN_AI_API_KEY=pat_bZkDGRm5634543xZVLltFwhgH2DNY",
                        "MODEL=",
                        "OPEN_AI_API_BASE=http://tongxinhuicoze2openai2:3000/v1",
                        "PROXY=",
                        "SINGLE_CHAT_PREFIX=['']",
                        "SINGLE_CHAT_REPLY_PREFIX='[AI] '",
                        "GROUP_CHAT_PREFIX=['@不擅奔跑常乃超']",
                        "GROUP_NAME_WHITE_LIST=['同心汇客服机器人演示群1', '同心汇客服机器人演示群2', '同心汇客服机器人演示群3', '同心汇客服机器人演示群4', '同心汇客服机器人演示群5', '同心汇客服机器人演示群6', '同心汇客服机器人演示群7', '同心汇客服机器人演示群8']",
                        "IMAGE_CREATE_PREFIX=['Drawing']",
                        "CONVERSATION_MAX_TOKENS=1000",
                        "SPEECH_RECOGNITION=False",
                        "CHARACTER_DESC=你是基于寿乡月嫂知识库的大语言模型智能助手，旨在回答并解决人们的学习AI遇到的问题，并且可以使用多种语言与人交流。",
                        "EXPIRES_IN_SECONDS=3600",
                        "USE_GLOBAL_PLUGIN_CONFIG=True",
                        "USE_LINKAI=False",
                        "LINKAI_API_KEY=",
                        "LINKAI_APP_CODE="
                )
                .exec();

        // 启动 tongxinhui-ai-bot 容器
        dockerClient.startContainerCmd(container.getId()).exec();

        // 创建 tongxinhuicoze2openai 容器
        CreateContainerResponse container2 = dockerClient.createContainerCmd("andywuwu/coze2openai:latest")
                .withName("tongxinhuicoze2openai2")
                .withRestartPolicy(RestartPolicy.alwaysRestart())
                .withNetworkMode(TONGXINHUI_NETWORK)
                .withEnv(
                        "BOT_ID=7424084534766372",
                        "COZE_API_BASE=api.coze.cn"
                )
                .exec();

        // 启动 tongxinhuicoze2openai 容器
        dockerClient.startContainerCmd(container2.getId()).exec();

        // 等待容器启动完成
        WaitContainerResultCallback waitContainerResultCallback = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()).awaitCompletion();
        WaitContainerResultCallback waitContainerResultCallback1 = dockerClient.waitContainerCmd(container2.getId()).exec(new WaitContainerResultCallback()).awaitCompletion();

        System.out.println("Containers started successfully.");
    }

    @Override
    public InspectContainerResponse getContainerInfo(String containerId) {
        return dockerClient.inspectContainerCmd(containerId).exec();
    }

    @Override
    public void updateContainer(String containerId, int cpuShares) {
        dockerClient.updateContainerCmd(containerId)
                .withCpuShares(cpuShares)
                .exec();
    }

    @Override
    public void deleteContainer(String containerId) {
        dockerClient.removeContainerCmd(containerId)
                .withForce(true)
                .exec();
    }

    @Override
    public void startContainer(String containerId) {
        dockerUtil.startContainer(containerId);
    }

    @Override
    public void stopContainer(String containerId) {
        dockerUtil.stopContainer(containerId);
    }

    @Override
    public List<String> getItChatQRCodeUrlByContainer(String containerName) {
        try {
            // 检查容器是否存在
            boolean containerExists = checkIfContainerExists(dockerClient, containerName);

            if (containerExists) {
                // 重启容器
                restartContainer(dockerClient, containerName);
            } else {
                // 创建并启动新容器
                try {
                    createContainer(DockerUtil.IMAGE_NAME, containerName);
                } catch (Exception e) {
                    if (e.getMessage().contains("is already in use")) {
                        dockerClient.restartContainerCmd(containerName).exec();
/*                        dockerClient.stopContainerCmd(containerName);
                        dockerClient.startContainerCmd(containerName);*/
                    } else {
                        System.out.println("启动：" + containerName + "失败");
                        e.printStackTrace();
                    }
                }
            }

            // 获取容器ID
//            String containerId = getContainerIdByName(dockerClient, containerName);

            // 获取容器日志并提取URL
            List<String> qrUrls = extractQrUrlsFromLogs(containerName);

            // 打印或处理提取的URL
            System.out.println("Extracted QR URLs: " + Joiner.on(", ").join(qrUrls));
            return qrUrls;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
/*            // 关闭Docker客户端
            try {
                dockerClient.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }*/
        }
        return Collections.emptyList();
    }


    private boolean checkIfContainerExists(DockerClient dockerClient, String containerName) {
        try {
            InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(containerName).exec();
            return inspectContainerResponse != null;
        } catch (Exception e) {
            return false;
        }
    }

    private void restartContainer(DockerClient dockerClient, String containerName) {
        dockerClient.restartContainerCmd(containerName).exec();
        System.out.println("Container restarted: " + containerName);
    }

    private String getContainerIdByName(DockerClient dockerClient, String containerName) {
        InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(containerName).exec();
        return inspectContainerResponse.getId();
    }

    private List<String> extractQrUrlsFromLogs(String containerId) throws Exception {
        List<String> qrUrls = new ArrayList<>();
        String host = "47.115.8.214";
        String user = "root";
        String password = "MiaoAI@2024s1";

        try {
            // 构建 grep 模式
            String grepPattern = Arrays.stream(WECHAT_LOGIN_QRCODE_URL_PREFIXES)
                    .map(prefix -> prefix.replace("?", "\\?"))
                    .collect(Collectors.joining("|", "^(", ")"));
            // 构建命令
            String command = "docker logs " + containerId + " | grep -E '" + grepPattern + "'";

            // 创建 JSch 实例
            JSch jsch = new JSch();
            Session session = jsch.getSession(user, host, 22);
            session.setPassword(password);

            // 设置不需要密钥交换
            session.setConfig("StrictHostKeyChecking", "no");

            // 连接到服务器
            session.connect();

            // 创建执行通道
            ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
            channelExec.setCommand(command);

            // 获取命令输出流
            InputStream in = channelExec.getInputStream();
            channelExec.setErrStream(System.err);

            // 启动命令
            channelExec.connect();

            // 读取输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line;
            while ((line = reader.readLine()) != null) {
                qrUrls.add(line);
                System.out.println(line);
            }

            // 关闭通道和会话
            channelExec.disconnect();
            session.disconnect();

        } catch (IOException | com.jcraft.jsch.JSchException e) {
            e.printStackTrace();
            System.err.println("Error executing command: " + e.getMessage());
        }
        return qrUrls.subList(qrUrls.size() - 4, qrUrls.size());
    }
}

